#!/usr/bin/env python
# -*- coding: utf-8 -*-

from HTMLParser import HTMLParser
import re
#module exceptions:
class ParseError(Exception):
     """The base class for all parse errors."""
     pass

#stack
class TagStack:
    def __init__(self):
	self.stack = []
	self.push_status = False
	pass

    def start_push(self):
	self.push_status = True


    def stop_push(self):
	self.push_status = False

    def push(self, x):
	if not self.push_status:
	    return
	self.stack.append(x)

    def pop(self, x):
	self.stack.pop(x)

    def is_empty(self):
	if len(self.stack) > 0 :
	    return False
	return True

    def clear(self):
	self.stack = []

#search condition class:
class SearchCondition:
    def __init__(self, tagname, cond_attrs ):
	self.tagname = tagname
	self.conds = {}
	for attr in cond_attrs:
	    self.conds[attr] = re.compile(cond_attrs[attr])

    def match_all(self, tag, attrs):
	if  tag != self.tagname :
	    return False
	if len(self.conds) == 0:
	    return True
	
	rets = dict()
	for x, y in attrs:
	    if x in self.conds:
		if self.conds[x].match(y) is None:
		    return False
		rets[x] = True

	for x in self.conds:
	    if x not in rets:
		return False
	return True

#single tag search
class SingleTagParser(HTMLParser):
    def __init__(self, tagname, cond_attrs = {}):
	"""search tag with attribute name and regular expression
	example1:
	    html:
	        <input type="textbox" name="JP" value ="Japan"/>
	    python:
        	parser = SingleTagParser('input', {'name': 'JP'})
		parser.feed(html)
		parser.close()
	        print parser.get_dict_name_value()
	        ----------------------------------------------------
	        {'JP': 'Japan'}
		print parser.get
	"""
	HTMLParser.__init__(self)
	self.__tagname = tagname
	self.__cond_attrs = SearchCondition(tagname, cond_attrs)
      	self.__result_nodes = []
	self.__dict__["RESULT"] = self.__result_nodes

    def clear(self):
	self.__result_nodes = []

    def get_dict_name_value(self):
	"""name/value attr"""
	rets = {}
	for item in self.__result_nodes:
	    if "name" in item:
		if "value" in item:
                    rets[item["name"]] =  item["value"]
                else:
                    rets[item["name"]] =  ""

	return rets

    def handle_starttag(self, tag, attrs):
	if self.__cond_attrs.match_all(tag, attrs):
	    ret = dict()
	    ret["tag"] = tag
	    for x, y in attrs:
		ret[x] = y
	    self.__result_nodes.append(ret)

    def handle_endtag(self, tag):
        pass

#multi tag search:
class MultiTagParser(HTMLParser):
    def __init__(self, cond_attrs_list = []):
	"""cond_attrs
	<input type="textbox" name="name1" value =""/>
	<input type="hidden"  name="hidden1" value="h"/>
	MultiTagParser([('input',{ 'name':'name1'}), (input', {'name':'hidden1'})])
	"""
	HTMLParser.__init__(self)
	self.cond_attrs_list = []
	self.cond_tag_list = []
	for cond in cond_attrs_list:
	    if not isinstance(cond, tuple):
		continue
	    if len(cond) != 2:
		continue
	    self.cond_attrs_list.append(SearchCondition(cond[0], cond[1]))
	    self.cond_tag_list.append(cond[0])
	
	self.result_nodes = []
	self.__dict__["RESULT"] = self.result_nodes

    def clear(self):
        self.result_nodes = []

    def get_dict_name_value(self):
        """name/value attr"""
        rets = {}
        for item in self.result_nodes:
            if "name" in item:
                if "value" in item:
                    rets[item["name"]] =  item["value"]
                else:
                    rets[item["name"]] =  ""

        return rets

    def is_match(self, tag, attrs):
	if tag not in self.cond_tag_list:
	    return False
	for cond in self.cond_attrs_list:
	    if cond.match_all(tag, attrs):
		return True
	return False


    def handle_starttag(self, tag, attrs):
        if self.is_match(tag, attrs):
            ret = dict()
            ret["tag"] = tag
            for x, y in attrs:
                ret[x] = y
            self.result_nodes.append(ret)

    def handle_endtag(self, tag):
        pass 
